package com.asambleacristiana.domain;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.asambleacristiana.utils.CommonUtils;

/**
 * Esta clase representa todos los movimientos contables que se producen en la
 * cuenta caja entre todas las zonas involucradas.
 * 
 * @author PBalegno
 * */
@Entity
@Table(name = "movimiento")
public class Movimiento {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "mov_codigo")
	private Long codigo;
	@ManyToOne
	@JoinColumn(name = "zn_codigo")
	private Zona zona;
	@Temporal(TemporalType.DATE)
	@Column(name = "fecha")
	private Date fecha;
	@ManyToOne
	@JoinColumn(name = "tp_codigo")
	private TipoOperacion tipoOperacion;
	@ManyToOne
	@JoinColumn(name = "cta_desde")
	private Cuenta desde;
	@ManyToOne
	@JoinColumn(name = "cta_hasta")
	private Cuenta hasta;

	@Column(name = "importe")
	private Double importe;

	@Column(name = "detalle")
	private String detalle;

	@SuppressWarnings("unused")
	@Column(name = "fecha_alta")
	private Date fechaAlta;

	@SuppressWarnings("unused")
	@Column(name = "usu_alta")
	private String usuAlta;

	@Column(name = "nro_factura")
	private String nroFactura;

	@Column(name = "tipo_factura")
	@Enumerated(EnumType.STRING)
	private TipoComprobanteEnum tipoFactura;

	@Column(name = "cuit")
	private String nroCuit;

	@Column(name = "fecha_baja")
	private Date fechaBaja;

	@Column(name = "usu_baja")
	private String usuBaja;

	public Movimiento() {
	}

	public Movimiento(Zona zona, Date fecha, TipoOperacion tipoOperacion, Cuenta desde, Cuenta hasta, Double importe, String detalle, String apodoUsu,
			TipoComprobanteEnum tipoFactura, String nroFactura, String nroCuit) {
		this.zona = zona;
		this.fecha = fecha;
		this.tipoOperacion = tipoOperacion;
		this.desde = desde;
		this.hasta = hasta;
		setImporte(importe);
		this.detalle = detalle;
		this.nroFactura = nroFactura;
		this.tipoFactura = tipoFactura;
		this.nroCuit = nroCuit;
		this.usuAlta = apodoUsu;
		this.fechaAlta = new Date();
	}

	public Long getCodigo() {
		return codigo;
	}

	public Zona getZona() {
		return zona;
	}

	public Date getFecha() {
		return fecha;
	}

	public TipoOperacion getTipoOperacion() {
		return tipoOperacion;
	}

	public Cuenta getDesde() {
		return desde;
	}

	public Cuenta getHasta() {
		return hasta;
	}

	public Double getImporte() {
		return importe;
	}

	public String getDetalle() {
		return detalle;
	}

	public void setNroFactura(String nroFactura) {
		this.nroFactura = nroFactura;
	}

	public String getNroFactura() {
		return nroFactura;
	}

	public TipoComprobanteEnum getTipoFactura() {
		return tipoFactura;
	}

	public String getNroCuit() {
		return nroCuit;
	}

	public void setFechaBaja(Date fechaBaja) {
		this.fechaBaja = fechaBaja;
	}

	public Date getFechaBaja() {
		return fechaBaja;
	}

	public void setUsuBaja(String usuBaja) {
		this.usuBaja = usuBaja;
	}

	public String getUsuBaja() {
		return usuBaja;
	}
	
	public void setDesde(Cuenta desde) {
		this.desde = desde;
	}
	
	public void setHasta(Cuenta hasta) {
		this.hasta = hasta;
	}
	
	public void setZona(Zona zona) {
		this.zona = zona;
	}
	
	public void setImporte(Double importe) {
		this.importe = CommonUtils.redondear(importe, 2);
	}
	
	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}
	public void setDetalle(String detalle) {
		this.detalle = detalle;
	}
	
	public void setTipoFactura(TipoComprobanteEnum tipoFactura) {
		this.tipoFactura = tipoFactura;
	}
	
	public void setNroCuit(String nroCuit) {
		this.nroCuit = nroCuit;
	}
	
	@Override
	public String toString() {
		return zona.getCodigo() + "-" + (tipoOperacion.equals(TipoOperacionEnum.ingreso) ? hasta.getCodigo() : desde.getCodigo() ) + "-" + codigo;
	}

	public String getNroComprobante(){
		return toString();
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((desde == null) ? 0 : desde.hashCode());
		result = prime * result + ((fecha == null) ? 0 : fecha.hashCode());
		result = prime * result + ((hasta == null) ? 0 : hasta.hashCode());
		result = prime * result + ((importe == null) ? 0 : importe.hashCode());
		result = prime * result + ((nroCuit == null) ? 0 : nroCuit.hashCode());
		result = prime * result + ((nroFactura == null) ? 0 : nroFactura.hashCode());
		result = prime * result + ((tipoFactura == null) ? 0 : tipoFactura.hashCode());
		result = prime * result + ((tipoOperacion == null) ? 0 : tipoOperacion.hashCode());
		result = prime * result + ((zona == null) ? 0 : zona.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Movimiento other = (Movimiento) obj;
		if (desde == null) {
			if (other.desde != null)
				return false;
		} else if (!desde.equals(other.desde))
			return false;
		if (fecha == null) {
			if (other.fecha != null)
				return false;
		} else if (!fecha.equals(other.fecha))
			return false;
		if (hasta == null) {
			if (other.hasta != null)
				return false;
		} else if (!hasta.equals(other.hasta))
			return false;
		if (importe == null) {
			if (other.importe != null)
				return false;
		} else if (!importe.equals(other.importe))
			return false;
		if (nroCuit == null) {
			if (other.nroCuit != null)
				return false;
		} else if (!nroCuit.equals(other.nroCuit))
			return false;
		if (nroFactura == null) {
			if (other.nroFactura != null)
				return false;
		} else if (!nroFactura.equals(other.nroFactura))
			return false;
		if (tipoFactura != other.tipoFactura)
			return false;
		if (tipoOperacion == null) {
			if (other.tipoOperacion != null)
				return false;
		} else if (!tipoOperacion.equals(other.tipoOperacion))
			return false;
		if (zona == null) {
			if (other.zona != null)
				return false;
		} else if (!zona.equals(other.zona))
			return false;
		return true;
	}

}
